﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using SyncLib.Client;
using SyncLib.Interface;
using SyncLib;
using log4net;
using System.ServiceModel;
using SyncLib.Data;
using System.Windows.Forms;
using System.Diagnostics;

namespace SyncApplication.Business
{
    public class SynchronizeHandle
    {
        static ILog Log = LogManager.GetLogger(typeof(Log4NetImplement));
        //ProxyInfo<ISyncManager> OneProxy;
        WCFConnection WcfConnection;
        public void ManualSynchronize()
        {
            if (MonitorEvent.Monitor is QuietMonitorEvent)
                MonitorEvent.Monitor = new GridMonitorEvent();
            bool finishNormal = true;
            ClientSyncContext.UserCancel = false;
            SyncDialog.Current.Show();
            SyncDialog.Current.Begin();
            ClientSyncContext.TaskIndex = -1;
            ClientSyncContext.SyncDS.AcceptChanges();

            Thread runThread = new Thread(new ThreadStart(delegate
            {
                string scopeName = "Unknown";
                try
                {
                    ClientSyncContext.IsRunning = true;
                    ClientSyncContext.UserCancel = false;
                    FrmNotify.Current.Animation(AnimationState.Syncing);
                    Log.DebugFormat("Bắt đầu đồng bộ(Count={0})", ClientSyncContext.SyncDS.TaskSyncList.Count);
                    foreach (ClientSyncDS.TaskSyncListRow task in ClientSyncContext.SyncDS.TaskSyncList)
                    {

                        ClientSyncContext.TaskIndex++;

                        FrmNotify.Current.NextTask(task);

                        if (!ClientSyncContext.CreateProxyPerTask)
                            CheckProxyState();
                        scopeName = task.ScopeName;
                        if (ClientSyncContext.UserCancel)
                            break;
                        if (task.StatusCode == ClientConst.TaskPending)
                        {
                            PerformSynchronize p = new PerformSynchronize(task);
                            if (!ClientSyncContext.CreateProxyPerTask)
                                p.ProxyInfo = WcfConnection.ProxyInfo;
                            p.Synchronize();
                            if (p.ResultCode != "-1")
                                task.SessionId = p.SessionId;

                        }



                    }
                }
                catch (Exception ex)
                {
                    finishNormal = false;
                    if (ClientSyncContext.CurrentTask != null)
                    {
                        ClientSyncContext.CurrentTask.StatusCode = ClientConst.TaskError;
                        ClientSyncContext.CurrentTask.Status = ClientConst.DesTaskError;
                        ClientSyncContext.CurrentTask.Message = ex.Message;
                        ClientSyncContext.CurrentTask.Image = AnimationGrid.ImgError;
                    }
                    ClientSyncContext.AppIssue("-1", "Lỗi đồng bộ thủ công[" + scopeName + "]", ex.ToString());
                    Log.Fatal("ManualSynchronize Exception:", ex);
                    FrmNotify.Current.ShowError();
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    Log.DebugFormat("Số Task đã duyệt {0}", ClientSyncContext.TaskIndex);
                    ClientSyncContext.IsRunning = false;
                    CloseWCFClient();
                    SyncDialog.Current.End(finishNormal);
                    FrmNotify.Current.Animation(AnimationState.Normal);
                }
            }));
            runThread.Start();
        }
        public void AutomaticSynchronize()
        {
            Log.Info("*****************************************************************");
            Log.Info("****************Bắt đầu tự động đồng bộ*****************");
            Log.Info("*****************************************************************");
            ClientSyncContext.CurrentTask = null;
            ClientSyncContext.UserCancel = false;
            if (MonitorEvent.Monitor is QuietMonitorEvent)
                MonitorEvent.Monitor = new GridMonitorEvent();
            bool finishNormal = true;
            ClientSyncContext.SyncDS.TaskSyncList.Clear();
            ClientSyncContext.AddScopeToTaskList("Lấy danh sách phạm vi");
            ClientSyncContext.SyncDS.AcceptChanges();
            if (SyncDialog.ShowWhenSync)
                SyncDialog.Current.Show();
            SyncDialog.Current.Begin();
            ClientSyncContext.TaskIndex = 0;

            Thread runThread = new Thread(new ThreadStart(delegate
            {
                FrmNotify.Current.Animation(AnimationState.Syncing);
                string scopeName = "Unknown";
                AnimationGrid animation = null;

                try
                {
                    ClientSyncContext.IsRunning = true;
                    ClientSyncContext.OnSyncProcess(EventType.BeginSync);
                    ClientSyncDS.TaskSyncListRow task1 = ClientSyncContext.SyncDS.TaskSyncList[0];
                    ClientSyncContext.CurrentTask = task1;
                    //ClientSyncContext.TaskIndex = 0;
                    animation = new AnimationGrid();
                    animation.Start();
                    FrmNotify.Current.NextTask(task1);
                    Log.Debug("Lấy danh sách phạm vi cần đồng bộ");
                    Log.Debug("     Khởi tạo proxy");
                    MonitorEvent.Monitor.Info("Tạo proxy");

                    CheckProxyState();

                    Log.Debug("     Lấy danh sách phạm vi từ máy chủ");
                    ScopeInfoEx[] scopes = WcfConnection.ProxyInfo.Channel.GetScopeInfo((Guid)CommonVariable.Get(ClientConst.ClientID));
                    animation.Success();
                    Log.DebugFormat("     Đã lấy được {0} phạm vi", scopes.Length);
                    Log.DebugFormat("--End");
                    MonitorEvent.Monitor.Info("Tạo danh sách đồng bộ");
                    // Thread.Sleep(10000);
                    animation.Dispose();
                    Log.Debug("Tạo danh sách đồng bộ");
                    Log.DebugFormat("      Xóa danh sách Task đang có {0}", ClientSyncContext.SyncDS.TaskSyncList.Count);

                    //SyncDialog.Current.GridMain.Invoke(new MethodInvoker(delegate
                    //{
                    //    SyncDialog.Current.DetachDataSource();
                    //    ClientSyncContext.CurrentTask = null;
                    //    ClientSyncContext.SyncDS.TaskSyncList.Clear();
                    //    ClientSyncContext.SyncDS.TaskSyncList.AcceptChanges();
                    //    SyncDialog.Current.RefreshDatasource();
                    //}));
                    ClientSyncContext.CurrentTask = null;
                    ClientSyncContext.SyncDS.TaskSyncList.Clear();
                    Thread.Sleep(1000);

                    foreach (ScopeInfoEx node in scopes)
                    {

                        ClientSyncContext.AddScopeToTaskList(node.ScopeName, node);
                        Log.DebugFormat("   Thêm phạm vi {0} vào danh sách ", node.ScopeName);

                        Thread.Sleep(100);
                    }
                    Log.Debug("--End");
                    SyncDialog.Current.InvokeRefresh();
                    Thread.Sleep(1000);
                    ClientSyncContext.TaskIndex = -1;
                    Log.Debug("Bắt đầu đồng bộ");
                    foreach (ClientSyncDS.TaskSyncListRow task in ClientSyncContext.SyncDS.TaskSyncList)
                    {
                        ClientSyncContext.TaskIndex++;
                        //SyncDialog.Current.HighlightNode(ClientSyncContext.TaskIndex);
                        Log.DebugFormat("   Lấy phạm vi {0} từ danh sách đồng bộ(Index={1}", task.ScopeName, ClientSyncContext.TaskIndex);
                        FrmNotify.Current.NextTask(task);
                        if (!ClientSyncContext.CreateProxyPerTask)
                            CheckProxyState();
                        scopeName = task.ScopeName;
                        if (ClientSyncContext.UserCancel)
                        {
                            Log.Debug("     BREAK -- UserCancel=True");
                            break;
                        }
                        if (task.StatusCode == ClientConst.TaskPending)
                        {
                            ScopeInfoEx scopeTemp = task.Tag as ScopeInfoEx;

                            PerformSynchronize p = new PerformSynchronize(task, scopeTemp);
                            if (!ClientSyncContext.CreateProxyPerTask)
                                p.ProxyInfo = WcfConnection.ProxyInfo;
                            p.Synchronize();
                            if (p.ResultCode != "-1")
                                task.SessionId = p.SessionId;
                        }
                        Log.DebugFormat("       Kết thúc phạm vi {0}", task.ScopeName);

                        SyncDialog.Current.InvokeRefresh();

                    }

                }
                catch (Exception ex)
                {
                    //   animation.Error();
                    ClientSyncContext.AppIssue("-1", "Lỗi đồng bộ tự động[" + scopeName + "]", ex.ToString());
                    Log.Fatal("AutomaticSynchronize Exception:", ex);
                    //SyncDialog.Current.SetStatus(scopeName, ClientConst.TaskError);
                    //SyncDialog.Current.SetMessage(scopeName, ex.Message);
                    MonitorEvent.Monitor.Info(ex.Message);
                    if (ClientSyncContext.CurrentTask != null)
                    {
                        ClientSyncContext.CurrentTask.StatusCode = ClientConst.TaskError;
                        ClientSyncContext.CurrentTask.Status = ClientConst.DesTaskError;
                    }
                    finishNormal = false;
                    SyncDialog.Current.DisplayMessage("Có lỗi khi thực hiện");
                    FrmNotify.Current.ShowError();
                }
                finally
                {
                    Log.DebugFormat("Kết thúc đồng bộ(Count{0})", ClientSyncContext.TaskIndex);
                    SyncDialog.Current.InvokeRefresh();
                    ClientSyncContext.IsRunning = false;
                    CloseWCFClient();
                    SyncDialog.Current.End(finishNormal);
                    FrmNotify.Current.Animation(AnimationState.Normal);
                    ClientSyncContext.OnSyncProcess(EventType.FinishSync);
                }
            }));
            runThread.Start();
        }
        void CheckProxyState()
        {
            if (WcfConnection == null || WcfConnection.ProxyInfo.ChannelFactory.State == CommunicationState.Faulted || WcfConnection.ProxyInfo.ChannelFactory.State == CommunicationState.Closed)
            {
                if (WcfConnection != null)
                    WcfConnection.Dispose();
                WcfConnection = new WCFConnection();
                WcfConnection.Open();

                try
                {
                    // MonitorEvent.Monitor.Info("Tạo kết nối tới máy chủ");
                    SyncDialog.Current.DisplayMessage("Tạo kết nối dùng chung");
                }
                catch
                {
                }

                try
                {
                    SyncDialog.Current.DisplayMessage("Đang thực hiện đồng bộ");
                }
                catch
                {
                }

            }


        }
        void CloseWCFClient()
        {
            try
            {
                if (WcfConnection != null)
                    WcfConnection.Close();
            }
            catch
            {
            }
            finally
            {
                // SyncDialog.Current.SetMessage("Đang thực hiện đồng bộ");
            }

        }
    }
}
